package com.znh.main;

import com.znh.Factory.PieceFactory;
import com.znh.common.Utils;
import com.znh.entity.*;
import com.znh.enums.PiecePlayerEnum;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;


/**
 * @version 1.0
 * @Author znh
 * @Date 2024/5/22 下午2:49
 * @注释 游戏面板
 */
public class GamePanel extends JPanel {
    /**
     * 前进按钮是否被点击
     */
    private boolean btn_forward_isClick = false;

    /**
     * 棋盘
     */
    Board board = new Board();

    public void setBtn_forward_isClick(boolean btn_forward_isClick) {
        this.btn_forward_isClick = btn_forward_isClick;
    }

    public GamePanel() {
        HashMap<Point, String> red = new HashMap<>();
        HashMap<Point, String> black = new HashMap<>();
        Point[] pointsRed = GameRule.LOCATION_POINT.get(GameRule.RED_LOCATION);
        Point[] pointsBlack = GameRule.LOCATION_POINT.get(GameRule.BLACK_LOCATION);
        for (int i = 0; i < pointsRed.length; i++) {
            red.put(pointsRed[i], GameRule.PIECES_NAME[i]);
        }
        for (int i = 0; i < pointsBlack.length; i++) {
            black.put(pointsBlack[i], GameRule.PIECES_NAME[i]);
        }
        createPieces(red, black);
        //鼠标点击事件
        addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (GameRule.getIsGameOver()){
                    //游戏结束
                    return;
                }
                //super.mouseClicked(e);
                Point point = calPointByXY(e.getX(), e.getY());
                if (!Board.isInboard(point)) {
                    //棋盘外
                    return;
                }
                Piece piece = GameRule.POINT_PIECE_MAP.get(point);
                if (piece == null && GameRule.SELECT_PIECE == null) {
                    return;
                } else if (piece != null && GameRule.SELECT_PIECE == null) {
                    //第一次选择
                    GameRule.SELECT_PIECE = piece;
                    if (GameRule.SELECT_PIECE.getPlayer() != GameRule.CUR_ROUND) //判断是否轮到你走
                    {
                        GameRule.SELECT_PIECE = null;
                        return;
                    }
                } else if (piece == null && GameRule.SELECT_PIECE != null) {
                    //移动
                    if (GameRule.SELECT_PIECE.simulateMove(point)) {
                        Piece actionPiece = Utils.deepClone(GameRule.SELECT_PIECE);
                        //更新棋子坐标
                        GameRule.removeCurPhaseMap(actionPiece);
                        GameRule.SELECT_PIECE.setPoint(point);
                        GameRule.addCurPhaseMap(GameRule.SELECT_PIECE);
                        //行棋记录
                        GameRule.addMemo(GameRule.CUR_ROUND, actionPiece, null, new Point(point.x, point.y));
                        //交换回合
                        GameRule.changeRound();
                        GameRule.SELECT_PIECE = null;
                        //获取当前局面评论
                        Comment.phase=Utils.phaseToString(GameRule.POINT_PIECE_MAP);
                        Comment.getComment();
                        //判断游戏是否结束
                        GameRule.setIsGameOver(GameRule.isGameOver());
                        //判断是否将军
                        if (!GameRule.getIsGameOver()&&GameRule.NAME_PIECE_MAP.get(GameRule.CUR_ROUND).get("boss").stream()
                                .anyMatch(boss -> ((Boss) boss).isNextEat())){
                            JOptionPane.showMessageDialog(null,"jiangjun",
                                    "Warning",JOptionPane.WARNING_MESSAGE);
                        }
                    }
                } else if (piece.getPlayer() == GameRule.SELECT_PIECE.getPlayer()) {
                    //重新选择
                    GameRule.SELECT_PIECE = piece;
                } else if (piece.getPlayer() != GameRule.SELECT_PIECE.getPlayer()) {
                    //吃子
                    if (GameRule.SELECT_PIECE.simulateMove(point)) {
                        Piece actionPiece = Utils.deepClone(GameRule.SELECT_PIECE);
                        Piece atePiece = Utils.deepClone(piece);
                        //更新棋子坐标
                        GameRule.removeCurPhaseMap(actionPiece);
                        GameRule.removeCurPhaseMap(atePiece);
                        GameRule.SELECT_PIECE.setPoint(point);
                        GameRule.addCurPhaseMap(GameRule.SELECT_PIECE);
                        //行棋记录
                        GameRule.addMemo(GameRule.CUR_ROUND, actionPiece, atePiece, new Point(point.x, point.y));
                        //交换回合
                        GameRule.changeRound();
                        GameRule.SELECT_PIECE = null;
                        //获取当前局面评论
                        Comment.phase=Utils.phaseToString(GameRule.POINT_PIECE_MAP);
                        Comment.getComment();
                        //判断游戏是否结束
                        GameRule.setIsGameOver(GameRule.isGameOver());
                        //判断是否将军
                        if (!GameRule.getIsGameOver()&&GameRule.NAME_PIECE_MAP.get(GameRule.CUR_ROUND).get("boss").stream()
                                .anyMatch(boss -> ((Boss) boss).isNextEat())){
                            JOptionPane.showMessageDialog(null,"jiangjun",
                                    "Warning",JOptionPane.WARNING_MESSAGE);
                        }
                    }
                } else {
                    System.out.println("其他情况，出错了");
                }
                //界面样式调整
                MainFrame.label_tip_setText();
                MainFrame.btn_regretForward_setEnable();
                repaint();
            }
        });
    }

    /**
     * 初始化棋盘 TODO:导入棋谱后行棋记录MEMOS已经有id，和新生成的棋子id不一致
     *
     * @param red   红方坐标->棋名集
     * @param black 黑方坐标->棋名集
     */
    public void createPieces(Map<Point, String> red, Map<Point, String> black) {
        int id = 0;
        GameRule.POINT_PIECE_MAP.clear();
        GameRule.NAME_PIECE_MAP.get(PiecePlayerEnum.RED).clear();
        GameRule.NAME_PIECE_MAP.get(PiecePlayerEnum.BLACK).clear();
        //红
        for (Map.Entry<Point, String> redEntry : red.entrySet()) {
            Point pointsRed = redEntry.getKey();
            String nameRed = redEntry.getValue();
            Piece piece = PieceFactory.createPiece(id++, nameRed, pointsRed, PiecePlayerEnum.RED,
                    GameRule.RED_LOCATION);
            GameRule.addCurPhaseMap(piece);
            //存档开局局面
            Point pointsRedInit = new Point(pointsRed.x, pointsRed.y);
            Piece pieceInit = PieceFactory.createPiece(piece.getId(), nameRed, pointsRedInit, PiecePlayerEnum.RED,
                    GameRule.RED_LOCATION);
            GameRule.INIT_POINT_PIECE_MAP.put(pointsRedInit, pieceInit);
        }
        //黑
        for (Map.Entry<Point, String> blackEntry : black.entrySet()) {
            Point pointsBlack = blackEntry.getKey();
            String nameBlack = blackEntry.getValue();
            Piece piece = PieceFactory.createPiece(id++, nameBlack, pointsBlack, PiecePlayerEnum.BLACK,
                    GameRule.BLACK_LOCATION);
            GameRule.addCurPhaseMap(piece);
            //存档开局局面
            Point pointsBlackInit = new Point(pointsBlack.x, pointsBlack.y);
            Piece pieceInit = PieceFactory.createPiece(piece.getId(), nameBlack, pointsBlackInit, PiecePlayerEnum.BLACK,
                    GameRule.BLACK_LOCATION);
            GameRule.INIT_POINT_PIECE_MAP.put(pointsBlackInit, pieceInit);
        }
        //保存初始局面到棋谱
        GameRule.INIT_PHASE[0] = Utils.phaseToString(GameRule.INIT_POINT_PIECE_MAP);
        GameRule.MANUAL.setInitPhase(GameRule.INIT_PHASE[0]);
        GameRule.setIsGameOver(GameRule.isGameOver());
    }

    //绘制棋盘
    private void drawBoard(Graphics g) {
        board.draw(g, this);
    }


    /**
     * 绘制前进提示选择线
     *
     * @param g
     */
    public void drawNextStepLine(Graphics g) {
        ArrayList<Memo> children = GameRule.CUR_MEMO.getChildren();
        if (children.size() <= 1) return;

        children.forEach(next_memo -> {
            Piece actionPiece = next_memo.getActionPiece();
            Point targetPoint = Piece.calCenterXYByPoint(next_memo.getTargetPoint());
            g.drawLine(actionPiece.getX() + Piece.WIDTH / 2, actionPiece.getY() + Piece.HEIGHT / 2, targetPoint.x, targetPoint.y);
        });
    }

    //绘制棋子
    private void drawPieces(Graphics g) {
        GameRule.POINT_PIECE_MAP.forEach((point, piece) -> piece.draw(g, this));
    }

    /**
     * 根据实际坐标计算出逻辑坐标
     *
     * @param x
     * @param y
     * @return
     */
    private Point calPointByXY(int x, int y) {
        //this.x=MARGIN-WIDTH/2+((int) point.getX()-1)*SPACE;
        return new Point((x + Piece.WIDTH / 2 - Piece.MARGIN) / Piece.SPACE + 1,
                (y + Piece.WIDTH / 2 - Piece.MARGIN) / Piece.SPACE + 1);
    }


    @Override
    public void paint(Graphics g) {
        //super.paint(g);
        //绘制棋盘
        drawBoard(g);
        //绘制棋子
        drawPieces(g);
        //选中边框提示
        if (GameRule.SELECT_PIECE != null) {
            GameRule.SELECT_PIECE.drawBorder(g, this);
        }
        //前进按钮被点击
        if (btn_forward_isClick) {
            drawNextStepLine(g);
            btn_forward_isClick = false;
        }
    }

}
